
#include "Input.h"

glm::vec2 Input::mouseScroll;
glm::vec2 Input::mousePosition;

GLFWwindow* Input::m_window = NULL;
std::vector<GLuint> Input::m_pressKeys;
GLboolean Input::m_midMouseBtn = GL_FALSE;
GLboolean Input::m_leftMouseBtn = GL_FALSE;
GLboolean Input::m_rightMouseBtn = GL_FALSE;

GLvoid Input::Init(GLFWwindow* window) {
	m_window = window;

	glfwSetCursorPosCallback(m_window, Mouse_Callback);
	glfwSetScrollCallback(m_window, Scroll_Callback);
	glfwSetMouseButtonCallback(m_window, MouseClick_Callback);
}

GLvoid Input::SetMouseCursor(GLint state) {
	glfwSetInputMode(m_window, GLFW_CURSOR, state);
}

GLboolean Input::GetKeyDown(GLuint keyCode) {
	if (glfwGetKey(m_window, keyCode) == GLFW_PRESS) {
		std::vector<GLuint>::iterator ret = std::find(m_pressKeys.begin(), m_pressKeys.end(), keyCode);
		if (ret == m_pressKeys.end()) {
			m_pressKeys.push_back(keyCode);
			return GL_TRUE;
		}
	}

	if (glfwGetKey(m_window, keyCode) == GLFW_RELEASE)
		for (std::vector<GLuint>::iterator it = m_pressKeys.begin(); it != m_pressKeys.end();)
			if (*it == keyCode)
				it = m_pressKeys.erase(it);
			else
				it++;

	return GL_FALSE;
}

GLboolean Input::GetKeyUp(GLuint keyCode) {
	return glfwGetKey(m_window, keyCode) == GLFW_RELEASE;
}

GLboolean Input::GetKey(GLuint keyCode) {
	return glfwGetKey(m_window, keyCode) == GLFW_PRESS;
}

GLboolean Input::GetMouseButton(GLint state) {
	switch (state)
	{
	case GLFW_MOUSE_BUTTON_LEFT:
		return m_leftMouseBtn;
	case GLFW_MOUSE_BUTTON_MIDDLE:
		return m_midMouseBtn;
	case GLFW_MOUSE_BUTTON_RIGHT:
		return m_rightMouseBtn;
	default:
		return GL_FALSE;
	}
}

GLvoid Input::Mouse_Callback(GLFWwindow* window, double xpos, double ypos) {
	mousePosition = glm::vec2(xpos, ypos);
}

GLvoid Input::Scroll_Callback(GLFWwindow* window, double xoffset, double yoffset) {
	mouseScroll = glm::vec2(xoffset, yoffset);
}

GLvoid Input::MouseClick_Callback(GLFWwindow* window, int button, int action, int mods) {
	if (action == GLFW_PRESS) switch (button)
	{
	case GLFW_MOUSE_BUTTON_LEFT:
		m_leftMouseBtn = GL_TRUE;
		break;
	case GLFW_MOUSE_BUTTON_MIDDLE:
		m_midMouseBtn = GL_TRUE;
		break;
	case GLFW_MOUSE_BUTTON_RIGHT:
		m_rightMouseBtn = GL_TRUE;
		break;
	default:
		return;
	}

	if (action == GLFW_RELEASE) switch (button)
	{
	case GLFW_MOUSE_BUTTON_LEFT:
		m_leftMouseBtn = GL_FALSE;
		break;
	case GLFW_MOUSE_BUTTON_MIDDLE:
		m_midMouseBtn = GL_FALSE;
		break;
	case GLFW_MOUSE_BUTTON_RIGHT:
		m_rightMouseBtn = GL_FALSE;
		break;
	default:
		return;
	}
}
